﻿using Microsoft.SqlServer.Server;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SqlSeverHepler
{
    public class SqlSeverHepler
    {
        // 提取 JSON 中指定键的值
        public static string GetJsonValue(string json, string key)
        {
            if (string.IsNullOrEmpty(json) || string.IsNullOrEmpty(key))
                return null;

            try
            {
                JObject jObject = JObject.Parse(json);
                return jObject[key]?.ToString();
            }
            catch (Exception)
            {
                // 处理 JSON 格式错误
                return null;
            }
        }

        /// <summary>
        /// 将DataTable（含动态字段）转换为JSON数组
        /// 支持任意字段名，无需预先定义实体类
        /// </summary>
        public static string ConvertDataTableToJson(DataTable table)
        {
            if (table == null || table.Rows.Count == 0)
                return "[]";

            // 构建动态字段列表
            var dynamicList = new List<Dictionary<string, object>>();

            foreach (DataRow row in table.Rows)
            {
                var rowData = new Dictionary<string, object>();
                foreach (DataColumn column in table.Columns)
                {
                    // 处理DBNull值
                    object value = row[column] == DBNull.Value ? null : row[column];
                    rowData[column.ColumnName] = value;
                }
                dynamicList.Add(rowData);
            }

            // 使用Newtonsoft.Json序列化
            return JsonConvert.SerializeObject(dynamicList, Formatting.Indented);
        }

        public static void SerializeQueryToJson(string querySql, out SqlString jsonResult)
        {
            jsonResult = SqlString.Null;
            if (string.IsNullOrEmpty(querySql))
            {
                SqlContext.Pipe.Send("错误：查询 SQL 不能为空");
                jsonResult = "错误：查询 SQL 不能为空";
                return;
            }

            // 简单的 SQL 注入防护（禁止危险操作）
            if (IsDangerousSql(querySql))
            {
                SqlContext.Pipe.Send("错误：SQL 包含危险操作（如 DELETE/UPDATE/DROP）");
                jsonResult = "错误：SQL 包含危险操作（如 DELETE/UPDATE/DROP/EXEC）";
                return;
            }

            // 使用当前数据库连接执行查询
            using (SqlConnection conn = new SqlConnection("context connection=true"))
            {
                try
                {
                    conn.Open();
                    using (SqlCommand cmd = new SqlCommand(querySql, conn))
                    {
                        // 限制为查询操作（防止执行非查询语句）
                        cmd.CommandType = CommandType.Text;

                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {
                            // 读取结果到 DataTable
                            DataTable dt = new DataTable();
                            dt.Load(reader);

                            // 序列化为 JSON
                            string json = JsonConvert.SerializeObject(dt, Formatting.None);
                            jsonResult = new SqlString(json);
                            SqlContext.Pipe.Send($"查询成功，返回 {dt.Rows.Count} 条记录");
                        }
                    }
                }
                catch (Exception ex)
                {
                    SqlContext.Pipe.Send($"执行错误：{ex.Message}");
                    jsonResult = ex?.Message;
                }
            }
        }

        /// <summary>
        /// 简单校验 SQL 是否包含危险操作（防注入）
        /// </summary>
        private static bool IsDangerousSql(string sql)
        {
            if (string.IsNullOrEmpty(sql)) return false;
            string lowerSql = sql.ToLower();
            // 禁止非查询操作（根据实际需求调整）
            string[] dangerousKeywords = { "delete", "update", "insert", "drop", "truncate", "alter", "exec" };
            foreach (var keyword in dangerousKeywords)
            {
                if (lowerSql.Contains(keyword))
                {
                    return true;
                }
            }
            return false;
        }

        public static void ParseJsonToArray(string jsonData)
        {
            if (string.IsNullOrEmpty(jsonData))
            {
                SqlContext.Pipe.Send("错误：JSON 数据不能为空");
                return;
            }

            try
            {
                // 解析 JSON 数组
                JArray jsonArray = JArray.Parse(jsonData);
                if (jsonArray.Count == 0)
                {
                    SqlContext.Pipe.Send("提示：JSON 数组为空");
                    return;
                }

                // 从第一个 JSON 对象提取列名
                JObject firstItem = jsonArray[0] as JObject;
                if (firstItem == null)
                {
                    SqlContext.Pipe.Send("错误：JSON 格式不正确，需为对象数组");
                    return;
                }

                // 1. 定义表结构（SqlMetaData 数组，对应列名和类型）
                SqlMetaData[] metaData = new SqlMetaData[firstItem.Properties().Count()];
                int colIndex = 0;
                foreach (var prop in firstItem.Properties())
                {
                    // 默认为字符串类型（可根据实际需求修改类型，如 SqlDbType.Int）
                    metaData[colIndex] = new SqlMetaData(prop.Name, SqlDbType.NVarChar, -1); // -1 表示最大长度
                    colIndex++;
                }

                // 2. 创建 SqlDataRecord（用于存储单行数据）
                SqlDataRecord record = new SqlDataRecord(metaData);

                // 3. 发送表头（通过发送空记录定义结构）
                SqlContext.Pipe.SendResultsStart(record);

                // 4. 遍历 JSON 数组，填充并发送每行数据
                foreach (JObject item in jsonArray)
                {
                    for (int i = 0; i < metaData.Length; i++)
                    {
                        string colName = metaData[i].Name;
                        JToken value = item[colName];
                        // 处理空值：若 JSON 字段不存在或为 null，设为 DBNull
                        string valueStr = value?.ToString();
                        record.SetValue(i, string.IsNullOrEmpty(valueStr) ? DBNull.Value : (object)valueStr);
                    }
                    // 发送当前行
                    SqlContext.Pipe.SendResultsRow(record);
                }

                // 5. 结束结果集发送
                SqlContext.Pipe.SendResultsEnd();
            }
            catch (JsonException ex)
            {
                SqlContext.Pipe.Send($"JSON 解析错误：{ex.Message}");
            }
            catch (Exception ex)
            {
                SqlContext.Pipe.Send($"执行错误：{ex.Message}");
            }
        }

    }
}
